# ==========================
#         导入依赖包
# ==========================
import time
import requests
import json
import uuid
import asyncio
from copy import deepcopy
from PIL import Image
import re

from aiooss2 import AioBucket
from oss2.auth import Auth
import io

# ==========================
#   OSS配置与工具类导入
# ==========================

class OssConfig:
    def __init__(self, access_key_id, access_key_secret, endpoint, bucket_name):
        self.access_key_id = access_key_id
        self.access_key_secret = access_key_secret
        self.endpoint = endpoint
        self.bucket_name = bucket_name

    @classmethod
    def from_dict(cls, d):
        return cls(
            access_key_id=d.get('access_key_id'),
            access_key_secret=d.get('access_key_secret'),
            endpoint=d.get('endpoint'),
            bucket_name=d.get('bucket_name'),
        )

class Config:
    def __init__(self, oss_config):
        self.oss_config = oss_config

    @classmethod
    def from_json(cls, json_str):
        d = json.loads(json_str)
        oss_dict = d.get('oss_config', {})
        oss_config = OssConfig.from_dict(oss_dict)
        return cls(oss_config=oss_config)

class OSSHandler:
    """
    阿里云OSS上传图片实现，基于aiooss2与oss2.auth。
    """
    def __init__(self, access_key_id, access_key_secret, endpoint, bucket_name):
        self.access_key_id = access_key_id
        self.access_key_secret = access_key_secret
        self.endpoint = endpoint
        self.bucket_name = bucket_name
        self.auth = Auth(self.access_key_id, self.access_key_secret)

    async def upload_images(self, filenames, images, imtype="PNG"):
        """
        异步上传多张图片到OSS，返回每个图片的url。
        filenames: ["a.png", ...]
        images: [PIL.Image对象, ...]
        """
        # images: List[PIL.Image]
        urls = []
        async with AioBucket(self.auth, self.endpoint, self.bucket_name) as bucket:
            for fn, img in zip(filenames, images):
                # 将PIL图像写入内存二进制流
                buffer = io.BytesIO()
                img.save(buffer, format=imtype)
                buffer.seek(0)
                data = buffer.getvalue()
                await bucket.put_object(fn, data)
                # 直接传递BytesIO对象而不是原始bytes，避免阻塞事件循环
                # await bucket.put_object(fn, buffer)
                urls.append(f"http://{self.bucket_name}.{self.endpoint}/{fn}")
        return urls

def get_oss():
    # 读取OSS配置
    with open('/home/zhangshu/project/algo_service/configs/config.json', 'r') as f:
        config = Config.from_json(f.read())

    oss_handler = OSSHandler(
        access_key_id=config.oss_config.access_key_id,
        access_key_secret=config.oss_config.access_key_secret,
        endpoint=config.oss_config.endpoint,
        bucket_name=config.oss_config.bucket_name,
    )
    return oss_handler

# ==========================
#      图片异步上传到OSS
# ==========================
'''test
image = Image.open(i['content'][0])
image_url = asyncio.run(upload_image(image))
messages.append({
    "role": i["role"],
    "content": [{
        "image_url": {
            "url": image_url
        },
        "type": "image_url"
    }]
})
'''
async def upload_image(oss, ref_image):
    if oss is None:
        oss = get_oss()
    """
    上传本地图片对象到OSS，并返回可用url
    """
    filenames = [f'test_tmp/{int(time.time() * 1000)}-{uuid.uuid4()}.png']
    ref_image_urls = await oss.upload_images(filenames, [ref_image], imtype="PNG")
    # print(ref_image_urls)
    return ref_image_urls[0]
